import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';

/// 支持的链接类型枚举
enum UrlLauncherType {
  url,          // 普通网址 (http/https)
  phone,        // 电话 (tel)
  sms,          // 短信 (sms)
  email,        // 邮件 (mailto)
  map,          // 地图位置 (geo)
  appStore,     // App Store (ios-app-store)
  playStore,    // Google Play (market)
  facetime,     // FaceTime (facetime)
  customScheme  // 自定义协议
}

/// 启动结果模型
class LaunchResult {
  final bool success;
  final String? message;
  final dynamic error;

  LaunchResult({
    required this.success,
    this.message,
    this.error,
  });
}

/// url_launcher工具类
class UrlLauncherUtils {
  /// 启动指定类型的链接
  static Future<LaunchResult> launch({
    required UrlLauncherType type,
    required String address,
    LaunchMode mode = LaunchMode.externalApplication,
    Map<String, String>? parameters, // 额外参数 (如邮件主题、正文)
  }) async {
    // 1. 验证地址不为空
    if (address.isEmpty) {
      return LaunchResult(
        success: false,
        message: '地址不能为空',
      );
    }

    // 2. 格式化并验证地址
    final formattedUrl = _formatAndValidateAddress(type, address, parameters);
    if (formattedUrl == null) {
      return LaunchResult(
        success: false,
        message: '无效的${_getTypeDescription(type)}地址',
      );
    }

    // 3. 检查是否可以启动
    if (!await canLaunchUrlString(formattedUrl)) {
      return LaunchResult(
        success: false,
        message: '无法启动${_getTypeDescription(type)}',
      );
    }

    // 4. 执行启动操作
    try {
      final result = await launchUrlString(
        formattedUrl,
        mode: mode,
      );
      return LaunchResult(
        success: result,
        message: result ? '${_getTypeDescription(type)}启动成功' : '启动失败',
      );
    } catch (e) {
      return LaunchResult(
        success: false,
        message: '${_getTypeDescription(type)}启动出错',
        error: e,
      );
    }
  }

  /// 格式化并验证地址
  static String? _formatAndValidateAddress(
      UrlLauncherType type,
      String address,
      Map<String, String>? parameters,
      ) {
    switch (type) {
      case UrlLauncherType.url:
        return _formatUrl(address);
      case UrlLauncherType.phone:
        return _formatPhone(address);
      case UrlLauncherType.sms:
        return _formatSms(address, parameters);
      case UrlLauncherType.email:
        return _formatEmail(address, parameters);
      case UrlLauncherType.map:
        return _formatMap(address);
      case UrlLauncherType.appStore:
        return _formatAppStore(address);
      case UrlLauncherType.playStore:
        return _formatPlayStore(address);
      case UrlLauncherType.facetime:
        return _formatFacetime(address);
      case UrlLauncherType.customScheme:
        return _formatCustomScheme(address);
    }
  }

  /// 获取类型描述
  static String _getTypeDescription(UrlLauncherType type) {
    switch (type) {
      case UrlLauncherType.url:
        return '网址';
      case UrlLauncherType.phone:
        return '电话';
      case UrlLauncherType.sms:
        return '短信';
      case UrlLauncherType.email:
        return '邮件';
      case UrlLauncherType.map:
        return '地图';
      case UrlLauncherType.appStore:
        return 'App Store';
      case UrlLauncherType.playStore:
        return '应用商店';
      case UrlLauncherType.facetime:
        return 'FaceTime';
      case UrlLauncherType.customScheme:
        return '自定义协议';
    }
  }

  /// 格式化URL
  static String? _formatUrl(String url) {
    if (url.isEmpty) return null;
    if (!url.startsWith(RegExp(r'^https?://', caseSensitive: false))) {
      url = 'https://$url';
    }
    return Uri.parse(url).isAbsolute ? url : null;
  }

  /// 格式化电话号码
  static String? _formatPhone(String phone) {
    if (phone.isEmpty) return null;
    // 移除所有非数字字符
    final cleaned = phone.replaceAll(RegExp(r'[^\d+]'), '');
    return cleaned.isNotEmpty ? 'tel:$cleaned' : null;
  }

  /// 格式化短信
  static String? _formatSms(String phone, Map<String, String>? parameters) {
    if (phone.isEmpty) return null;
    final cleanedPhone = phone.replaceAll(RegExp(r'[^\d+]'), '');
    if (cleanedPhone.isEmpty) return null;

    final uri = Uri(
      scheme: 'sms',
      path: cleanedPhone,
      queryParameters: parameters,
    );
    return uri.toString();
  }

  /// 格式化邮件
  static String? _formatEmail(String email, Map<String, String>? parameters) {
    if (email.isEmpty || !RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email)) {
      return null;
    }

    final uri = Uri(
      scheme: 'mailto',
      path: email,
      queryParameters: parameters,
    );
    return uri.toString();
  }

  /// 格式化地图位置
  static String? _formatMap(String location) {
    // 支持两种格式: 经纬度 "latitude,longitude" 或地址字符串
    if (location.isEmpty) return null;

    // 检查是否是经纬度格式
    if (RegExp(r'^-?\d+(\.\d+)?,-?\d+(\.\d+)?$').hasMatch(location)) {
      return 'geo:$location';
    }

    // 地址字符串格式
    return 'geo:0,0?q=${Uri.encodeComponent(location)}';
  }

  /// 格式化App Store链接
  static String? _formatAppStore(String appId) {
    if (appId.isEmpty) return null;
    return 'https://apps.apple.com/app/id$appId';
  }

  /// 格式化Play Store链接
  static String? _formatPlayStore(String packageName) {
    if (packageName.isEmpty) return null;
    return 'market://details?id=$packageName';
  }

  /// 格式化FaceTime
  static String? _formatFacetime(String address) {
    if (address.isEmpty) return null;
    // 支持电话号码或邮箱
    final isEmail = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(address);
    return isEmail ? 'facetime:$address' : 'facetime:tel:$address';
  }

  /// 格式化自定义协议
  static String? _formatCustomScheme(String scheme) {
    if (scheme.isEmpty || !scheme.contains(':')) return null;
    return scheme;
  }

  /// 显示结果提示
  static void showResultSnackbar(BuildContext context, LaunchResult result) {
    if (!context.mounted) return;

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(result.message ?? '操作完成'),
        backgroundColor: result.success ? Colors.green : Colors.red,
        behavior: SnackBarBehavior.floating,
      ),
    );
  }
}